package com.zmx.core.client.auth;

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.concurrent.BasicThreadFactory;

import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * @Description: 启动客户端 与服务端建立连接
 * @ClassName: StartClient
 * @Author zhaomxr
 * @Date 2021-12-16 10:34
 */
@Slf4j
public class StartClient {

    public StartClient() {
    }

    public StartClient(int port, String username, String password, String secret, String authUrl, int authRetryTime, int authHeartRetryTime) {
        this.start(port, username, password, secret, authUrl, authRetryTime, authHeartRetryTime);
    }

    private AtomicInteger atomicInteger = new AtomicInteger(0);

    private ScheduledFuture<?> scheduledFuture;

    /**
     * 开启服务注册
     *
     * @param port
     * @param username
     * @param password
     * @param secret
     * @param authUrl
     * @param authRetryTime
     * @param authHeartRetryTime
     * @return
     */
    private Client start(int port, String username, String password, String secret, String authUrl, int authRetryTime, int authHeartRetryTime) {
        Client client = new Client();
        Thread thread = new Thread(new Runnable() {
            @Override
            public void run() {

                try {
                    client.start(port, username, password, secret, authUrl, authRetryTime, authHeartRetryTime);
                    atomicInteger.incrementAndGet();
                } catch (Exception e) {
                    //设置为守护线程，不影响服务正常执行
                    ScheduledExecutorService executorService = new ScheduledThreadPoolExecutor(1,
                            new BasicThreadFactory.Builder().namingPattern("initClient").daemon(true).build());

                    scheduledFuture = executorService.scheduleAtFixedRate(new Runnable() {
                        @Override
                        public void run() {
                            try {
                                //如果认证成功，终止当前任务
                                if (atomicInteger.get() > 0) {
                                    scheduledFuture.cancel(true);
                                    scheduledFuture = null;
                                    return;
                                }

                                client.start(port, username, password, secret, authUrl, authRetryTime, authHeartRetryTime);

                                atomicInteger.incrementAndGet();
                            } catch (Throwable t) {
                                log.info("register to server {} fail!", authUrl);
                            }
                        }
                    }, 3, authRetryTime, TimeUnit.SECONDS);
                }
            }
        });

        thread.setDaemon(true);
        thread.start();
        return client;
    }
}
